package com.enation.app.javashop.core.promotion.seckill.service.impl;

import com.enation.app.javashop.core.promotion.seckill.model.dos.SeckillDO;
import com.enation.app.javashop.core.promotion.seckill.model.dos.SeckillRangeDO;
import com.enation.app.javashop.core.promotion.seckill.model.vo.TimeLineVO;
import com.enation.app.javashop.core.promotion.seckill.service.SeckillManager;
import com.enation.app.javashop.core.promotion.seckill.service.SeckillRangeManager;
import com.enation.app.javashop.core.promotion.tool.support.PromotionCacheKeys;
import com.enation.app.javashop.framework.cache.Cache;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.enation.app.javashop.framework.database.Page;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;

/**
 * 限时抢购时刻业务类
 *
 * @author Snow
 * @version v2.0.0
 * @since v7.0.0
 * 2018-04-02 18:24:47
 */
@Service
public class SeckillRangeManagerImpl implements SeckillRangeManager {

    @Autowired
    @Qualifier("tradeDaoSupport")
    private DaoSupport daoSupport;

    @Autowired
    private SeckillManager seckillManager;

    @Override
    public Page list(int page, int pageSize) {

        String sql = "select * from es_seckill_range  ";
        Page webPage = this.daoSupport.queryForPage(sql, page, pageSize, SeckillRangeDO.class);

        return webPage;
    }

    @Override
    public SeckillRangeDO edit(SeckillRangeDO seckillRange, Integer id) {
        this.daoSupport.update(seckillRange, id);
        return seckillRange;
    }

    @Override
    public void delete(Integer id) {
        this.daoSupport.delete(SeckillRangeDO.class, id);
    }

    @Override
    public SeckillRangeDO getModel(Integer id) {
        return this.daoSupport.queryForObject(SeckillRangeDO.class, id);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {ServiceException.class, RuntimeException.class})
    public void addList(List<Integer> list, Integer seckillId) {
        String sql = "delete from es_seckill_range where seckill_id=?";
        this.daoSupport.execute(sql, seckillId);
        List<Integer> termList = new ArrayList<>();
        for (Integer time : list) {
            termList.add(time);
            SeckillRangeDO seckillRangeDO = new SeckillRangeDO();
            seckillRangeDO.setSeckillId(seckillId);
            seckillRangeDO.setRangeTime(time);
            this.daoSupport.insert(seckillRangeDO);
        }
    }


    @Override
    public List<SeckillRangeDO> getList(Integer seckillId) {

        String sql = "select * from es_seckill_range where seckill_id=?";
        List<SeckillRangeDO> list = this.daoSupport.queryForList(sql, SeckillRangeDO.class, seckillId);
        return list;
    }


    @Override
    public List<TimeLineVO> readTimeList(String city) {
        long startDay =DateUtil.startOfTodDay();

        List<Object> term=new ArrayList<>();
        StringBuilder sql =new StringBuilder("select DISTINCT sr.*,s.* from es_seckill_range sr left join  es_seckill s on sr.seckill_id=s.seckill_id " +
                " inner join es_seckill_apply sa on sa.seckill_id = sr.seckill_id and sa.time_line = sr.range_time WHERE s.start_day = ? and status = 'PASS' ");
        term.add(startDay);
        if(!StringUtils.isEmpty(city)){
            SeckillDO seckillDO = seckillManager.getSeckillByCity(city,startDay);
            if (seckillDO == null) {
                return null;
            }
            sql.append(" and s.seckill_id=?");
            term.add(seckillDO.getSeckillId());
        }
        sql.append( " order by sr.range_time ");
        List<SeckillRangeDO> rangeDOList = this.daoSupport.queryForList(sql.toString(), SeckillRangeDO.class, term.toArray());

        //读取系统时间的时刻
        Calendar c = Calendar.getInstance();
        int currentHour = c.get(Calendar.HOUR_OF_DAY);

        Long currentTime=DateUtil.getDateline();


        List<TimeLineVO> resultTimeLine = new ArrayList<>();

        // 默认结束时间是 23:00:00
        long distanceEndTime = LocalDateTime.of(LocalDate.now(), LocalTime.of(23,0)).toInstant(ZoneOffset.of("+8")).toEpochMilli()/1000-DateUtil.getDateline();

        if(distanceEndTime<=0L){
             return resultTimeLine;
        }

        Boolean hasCurrent=false;
        for (int i = 0; i < rangeDOList.size(); i++) {
            SeckillRangeDO seckillRangeDO = rangeDOList.get(i);
            Integer rangeHour = seckillRangeDO.getRangeTime();
            long rangeTime = getTimeByHour(rangeHour);

            TimeLineVO timeLineVO = new TimeLineVO();
            timeLineVO.setEndDistanceTime(distanceEndTime);
            timeLineVO.setTimeText(rangeHour + "");

            // 1. 大于循环前面的时间,小于当前的时间
            if (rangeTime > currentTime && rangeHour <= currentHour) {
                timeLineVO.setDistanceTime(0L);
                timeLineVO.setStartStatus(1);
            }

            // 2. 小于于当前的小时数
            if (rangeHour <= currentHour) {
                timeLineVO.setDistanceTime(0L);
                timeLineVO.setStartStatus(1);
            }

            // 3. 大于当前的小时数
            if (rangeHour > currentHour) {
                timeLineVO.setDistanceTime(currentTime - rangeTime);
                timeLineVO.setStartStatus(0);
            }

            if (timeLineVO.getDistanceTime()<0L && i>0 && !hasCurrent) {
                // 部分活动开始了
                resultTimeLine.get(resultTimeLine.size()-1).setIsCurrent(1);
                hasCurrent=true;
            }else if(i==rangeDOList.size()-1 && timeLineVO.getDistanceTime()==0L){
                // 最后一个活动开始了
                timeLineVO.setIsCurrent(1);
                hasCurrent=true;
            }else {
                timeLineVO.setIsCurrent(0);
            }

            timeLineVO.setDistanceEndTime(timeLineVO.getEndDistanceTime());
            timeLineVO.setDistanceStartTime(timeLineVO.getDistanceTime());
            resultTimeLine.add(timeLineVO);
        }

        if(!hasCurrent){
            TimeLineVO timeLineVO = resultTimeLine.get(0);
            timeLineVO.setIsCurrent(1);
        }
        return resultTimeLine;
    }

    private long getTimeByHour(Integer hour) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String date = format.format(new Date());
        //限时抢购的时刻
        return DateUtil.getDateline(date + " " + hour, "yyyy-MM-dd HH");
    }

}
